import time
import serial
import binascii
from glr_message_parse import parse_message_xuji_698
from tools import deal_time, get_crc_16_x25_check, get_collect_err, modify_centos_date_restart, get_stand_time, \
    get_all_meter_addr


def stand_frozen_data(start_time, end_time, meter_addr, com_name):
    """
    站端发起冻结数据召测
    :param start_time:
    :param end_time:
    :param meter_addr:
    :param com_name:
    :return:
    """
    # 创建串口连接对象
    ser = serial.Serial()
    # 设置串口参数
    ser.port = com_name  # 串口设备路径
    ser.baudrate = 9600  # 波特率
    ser.bytesize = serial.EIGHTBITS  # 数据位长度为8位
    ser.parity = serial.PARITY_EVEN  # 无奇偶校验
    ser.stopbits = serial.STOPBITS_ONE  # 1位停止位
    ser.timeout = 1  # 读取超时时间为1秒

    # print(start_time)
    # print(end_time)

    deal_meter_addr = ' '.join([meter_addr[i:i + 2] for i in range(0, len(meter_addr), 2)][::-1])
    # print(deal_meter_addr)

    # 打开串口连接
    ser.open()

    check_code1 = get_crc_16_x25_check("40 00 43 05 {} 00".format(deal_meter_addr))
    check_code2 = get_crc_16_x25_check(
        "40 00 43 05 {} 00 {} 05 03 00 50 02 02 00 02 20 21 02 00 {} {} 54 01 00 0f 03 00 20 21 02 00 00 20 68 02 00 00 20 69 02 00 00".format(
            deal_meter_addr, check_code1, start_time, end_time))
    # 十六进制字符串
    hex_send = "68 40 00 43 05 {} 00 {} 05 03 00 50 02 02 00 02 20 21 02 00 {} {} 54 01 00 0f 03 00 20 21 02 00 00 20 68 02 00 00 20 69 02 00 00 {} 16".format(
        deal_meter_addr, check_code1, start_time, end_time, check_code2)  # 示例数据

    print("发送帧")
    print(hex_send)

    # 将十六进制字符串转换为字节串
    bytes_data = bytes.fromhex(hex_send)

    ser.write(bytes_data)  # 写入数据
    data = ser.readall()
    # print(data)
    ser.close()

    hex_recv = binascii.hexlify(data).decode("utf8")
    print("接收帧")
    print(hex_recv)
    transformer_address, collect_time, frequency, amplitude, phase, ratio, angle, status = parse_message_xuji_698(
        hex_recv)
    # print(transformer_address)
    # print(collect_time)
    # print(frequency)
    # print(amplitude)
    # print(phase)
    # print(ratio)
    # print(angle)
    # print(status)
    return transformer_address, collect_time, frequency, amplitude, phase, ratio, angle, status, hex_send.replace(
        " ", ""), hex_recv


def stand_event_data(meter_addr, com_name):
    """
    站端事件，目前未使用
    :param meter_addr:
    :param com_name:
    :return:
    """
    # 创建串口连接对象
    ser = serial.Serial()
    # 设置串口参数
    ser.port = com_name  # 串口设备路径
    ser.baudrate = 9600  # 波特率
    ser.bytesize = serial.EIGHTBITS  # 数据位长度为8位
    ser.parity = serial.PARITY_EVEN  # 无奇偶校验
    ser.stopbits = serial.STOPBITS_ONE  # 1位停止位
    ser.timeout = 1  # 读取超时时间为1秒

    # print(start_time)
    # print(end_time)

    deal_meter_addr = ' '.join([meter_addr[i:i + 2] for i in range(0, len(meter_addr), 2)][::-1])
    # print(deal_meter_addr)

    # 打开串口连接
    ser.open()

    num1 = "00"
    num2 = "01"
    check_code1 = get_crc_16_x25_check("47 00 43 05 {} 00".format(deal_meter_addr))
    check_code2 = get_crc_16_x25_check(
        "47 00 43 05 {} 00 {} 05 03 {} 30 4c 02 00 09 {} 09 00 20 22 02 00 00 20 1e 02 00 00 20 20 02 00 00 20 24 02 00 00 33 00 02 00 00 33 43 02 06 00 33 43 02 07 00 33 43 02 08 00 33 43 02 09 00".format(
            deal_meter_addr, check_code1, num1, num2))
    # 十六进制字符串
    hex_send = "68 47 00 43 05 {} 00 {} 05 03 {} 30 4c 02 00 09 {} 09 00 20 22 02 00 00 20 1e 02 00 00 20 20 02 00 00 20 24 02 00 00 33 00 02 00 00 33 43 02 06 00 33 43 02 07 00 33 43 02 08 00 33 43 02 09 00 {} 16".format(
        deal_meter_addr, check_code1, num1, num2, check_code2)  # 示例数据

    print("发送帧")
    print(hex_send)

    # 将十六进制字符串转换为字节串
    bytes_data = bytes.fromhex(hex_send)

    ser.write(bytes_data)  # 写入数据
    data = ser.readall()
    # print(data)
    ser.close()

    hex_recv = binascii.hexlify(data).decode("utf8")
    print("接收帧")
    print(hex_recv)
    # transformer_address, collect_time, frequency, amplitude, phase, ratio, angle, status = parse_message_xuji_698(
    #     hex_recv)
    # print(transformer_address)
    # print(collect_time)
    # print(frequency)
    # print(amplitude)
    # print(phase)
    # print(ratio)
    # print(angle)
    # print(status)
    return True


def get_stand_sql_data(start_time, end_time, meter_addr, com_name, ip):
    """
    发起站端召测并获取站端返回报文和sql数据
    获取数据库数据，适用于不修改站端时间发起召测
    :param start_time:
    :param end_time:
    :param meter_addr:
    :param com_name:
    :param ip:
    :param q:
    :return:
    """
    time.sleep(1)
    transformer_address, collect_time, frequency, amplitude, phase, ratio, angle, status, hex_send, hex_recv = \
        stand_frozen_data(start_time, end_time, meter_addr, com_name)
    sql_frequency, sql_amplitude, sql_phase, sql_ratio_error, sql_angle_error, sql_status = get_collect_err(
        ip, meter_addr, collect_time)
    return {"message_data": [transformer_address, collect_time, frequency, amplitude, phase, ratio, angle, status],
            "sql_data": [sql_frequency, sql_amplitude, sql_phase, sql_ratio_error, sql_angle_error, sql_status],
            "hex_send": hex_send,
            "hex_recv": hex_recv}


def modify_time_forzen(ip, com_name, modify_stand_time):
    """
    修改站端时间为指定之间并发起召测
    不获取数据库数据，适用于修改站端时间再发起召测
    :param ip:
    :param com_name:
    :param modify_stand_time:
    :return:
    """
    modify_centos_date_restart(ip, modify_stand_time.strftime("%Y-%m-%d %H:%M:%S"))
    # 获取restart后站端时间
    stand_time, stand_datetime = get_stand_time(ip)
    sleep_second = (modify_stand_time.replace(minute=15) - stand_datetime).total_seconds()
    assert sleep_second > 0, "重启后时间超过整15分钟：{}".format(stand_time)
    # 等待15分钟整点
    time.sleep(sleep_second)

    # 2、发起召测并解析报文
    list_meter_addr = get_all_meter_addr(ip)
    start_time = deal_time(modify_stand_time.replace(minute=0).strftime("%Y-%m-%d %H:%M:%S"))
    end_time = deal_time(modify_stand_time.replace(minute=15).strftime("%Y-%m-%d %H:%M:%S"))
    transformer_address, collect_time, frequency, amplitude, phase, ratio, angle, status, _, _ = stand_frozen_data(
        start_time, end_time, list_meter_addr[0], com_name)
    print(transformer_address, collect_time, frequency, amplitude, phase, ratio, angle, status)
    return transformer_address, collect_time, frequency, amplitude, phase, ratio, angle, status


if __name__ == '__main__':
    start_time = deal_time("2024-07-15 10:30:00")
    end_time = deal_time("2024-07-15 10:45:00")
    # stand_frozen_data(start_time, end_time, meter_addr, com_name)

    meter_addr = "111111110001"
    com_name = 'com4'
    stand_event_data(meter_addr, com_name)
